﻿namespace Filters.Demo
{
    using System;
    using System.Globalization;
    using System.Linq;
    using System.Windows.Forms;
    using Filters.Demo.Core;
    using Filters.Demo.DataAccess;
    using Filters.Demo.MetricSpaces;

    public static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        public static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Application.ThreadException += (s, e) => HandleException(e.Exception);
                AppDomain.CurrentDomain.UnhandledException += (s, e) => HandleException(e.ExceptionObject as Exception);
                Application.SetCompatibleTextRenderingDefault(false);

                try
                {
                    Application.Run(new MainForm(new ImageCatalogRepository(), new MetricSpacesHelper()));
                }
                catch (Exception exception)
                {
                    HandleException(exception);
                }

                return;
            }

            if (args.Length != 3)
            {
                PrintUsage();
                return;
            }

            try
            {
                var inputPath = args[0];
                var outputPath = args[1];
                var filtersFile = args[2];
                IImageFilter batchImageFilter = new BatchImageFilter(inputPath);
                IFilterApplierEngine filterEngine = new FilterApplierEngine(batchImageFilter);

                batchImageFilter.FilterApplied += BatchImageFilterFilterApplied;

                // apply all the filters to the images in the inputPath directory
                Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Applying filters to images at {0}...", inputPath));
                filterEngine.ApplyFilters(filtersFile);
                Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Filters applied successfully!", inputPath));

                Console.WriteLine();

                // apply the images to the outputPath directory
                Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Saving output images to {0}...", outputPath));
                filterEngine.Save(outputPath);
                Console.WriteLine("Images saved succesfully!");
            }
            catch (Exception exception)
            {
                Console.Error.WriteLine("ERROR:");
                Console.Error.WriteLine(exception.Message);
                Console.Error.WriteLine();

                PrintUsage();
            }
            finally
            {
                Console.ReadKey();
            }
        }

        private static void PrintUsage()
        {
            Console.WriteLine("USAGE:");
            Console.WriteLine("\tFILTERS.DEMO.EXE inputPath outputPath filtersFile");
            Console.WriteLine();
            Console.WriteLine("WHERE:");
            Console.WriteLine("\tinputPath\tDirectory where the images will be taken");
            Console.WriteLine("\toutputPath\tDirectory where the processed images will be saved");
            Console.WriteLine("\tfiltersFile\tXML file with the configuration of the filters");
        }

        private static void BatchImageFilterFilterApplied(object sender, FilterEventArgs e)
        {
            Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Filter Applied: {0}", e.Filters.LastOrDefault()));
        }

        private static void HandleException(Exception exception)
        {
            if (exception != null)
            {
                MessageBox.Show(
                    string.Format(CultureInfo.CurrentCulture, "An unhandled exception occurred, and the application is terminating: {0}", exception.Message),
                    "Unhandled Exception",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                Application.Exit();
            }
        }
    }
}
